package main

import (
	"encoding/json"
	"fmt"
	"math"
	"regexp"
	"sort"
	"strconv"
	"strings"
)

// ResistorResult 表示电阻计算的结果
type ResistorResult struct {
	TargetResistance string               `json:"targetResistance"`
	ClosestSingle    SingleResistorResult `json:"closestSingle"`
	SeriesCombos     []CombinationResult  `json:"seriesCombinations"`
	ParallelCombos   []CombinationResult  `json:"parallelCombinations"`
}

// SingleResistorResult 表示单个电阻结果
type SingleResistorResult struct {
	Value string  `json:"value"`
	Error float64 `json:"errorPercentage"`
}

// CombinationResult 表示电阻组合结果
type CombinationResult struct {
	R1    string  `json:"r1"`
	R2    string  `json:"r2"`
	Total string  `json:"total"`
	Error float64 `json:"errorPercentage"`
}

var E24 = [...]float64{1.0, 1.1, 1.2, 1.3, 1.5, 1.6, 1.8, 2.0, 2.2, 2.4, 2.7,
	3.0, 3.3, 3.6, 3.9, 4.3, 4.7, 5.1, 5.6, 6.2, 6.8,
	7.5, 8.2, 9.1}

func Generate_all_e24_values(min int, max int) []float64 {
	var all_values []float64
	for i := min; i <= max; i++ {
		for _, base := range E24 {
			all_values = append(all_values, base*float64(math.Pow(10, float64(i))))
		}
	}
	return all_values
}

func Parse_resistance(resistance_str string) float64 {
	resistance_str = strings.TrimSpace(resistance_str)
	resistance_str = strings.ToUpper(resistance_str)

	// 正则表达式匹配数字和单位
	re := regexp.MustCompile(`^([\d]+\.?[\d]*)([KMR])?$`)
	matches := re.FindStringSubmatch(resistance_str)
	if len(matches) < 3 {
		panic(fmt.Sprintf("无效的电阻值格式: %s", resistance_str))
	}

	value, err := strconv.ParseFloat(matches[1], 64)
	if err != nil {
		panic(fmt.Sprintf("无效的数字格式: %s", matches[1]))
	}

	unit := matches[2]

	// 根据单位转换为欧姆
	switch unit {
	case "K":
		value *= 1000
	case "M":
		value *= 1000000
		// 默认单位是欧姆，不做转换
	}

	return value
}

func Format_resistance(value float64) string {
	if value >= 1000000 {
		return fmt.Sprintf("%.2fM", value/1000000)
	} else if value >= 1000 {
		return fmt.Sprintf("%.2fK", value/1000)
	} else {
		return fmt.Sprintf("%.2f", value)
	}
}

func Find_closest_single_resistor(target float64, all_values []float64) (float64, float64) {
	closest := all_values[0]
	minError := math.Abs(closest-target) / target
	for _, value := range all_values {
		error := math.Abs(value-target) / target
		if error < minError {
			minError = error
			closest = value
		}
	}
	return closest, minError
}
func FindSeriesCombinations(target float64, allValues []float64, maxResults int) [][4]float64 {
	var results [][4]float64

	// 只考虑小于目标值的电阻
	validValues := make([]float64, 0)
	for _, v := range allValues {
		if v < target {
			validValues = append(validValues, v)
		}
	}

	for i, r1 := range validValues {
		for _, r2 := range validValues[i:] { // 从i开始避免重复组合
			total := r1 + r2
			error := math.Abs(total-target) / target
			results = append(results, [4]float64{r1, r2, total, error})
		}
	}

	// 按误差排序
	sort.Slice(results, func(i, j int) bool {
		return results[i][3] < results[j][3]
	})

	// 返回前 maxResults 个结果
	if len(results) > maxResults {
		return results[:maxResults]
	}
	return results
}

func FindParallelCombinations(target float64, allValues []float64, maxResults int) [][4]float64 {
	var results [][4]float64

	// 只考虑大于目标值的电阻
	validValues := make([]float64, 0)
	for _, v := range allValues {
		if v > target {
			validValues = append(validValues, v)
		}
	}

	for i, r1 := range validValues {
		for _, r2 := range validValues[i:] { // 从i开始避免重复组合
			// 并联电阻计算公式: 1/R = 1/R1 + 1/R2
			total := (r1 * r2) / (r1 + r2)
			error := math.Abs(total-target) / target
			results = append(results, [4]float64{r1, r2, total, error})
		}
	}

	// 按误差排序
	sort.Slice(results, func(i, j int) bool {
		return results[i][3] < results[j][3]
	})

	// 返回前 maxResults 个结果
	if len(results) > maxResults {
		return results[:maxResults]
	}
	return results
}

// CalculateResistorOptions 计算给定电阻值的各种可能组合，并返回JSON格式的结果
func CalculateResistorOptions(resistanceStr string) (string, error) {
	// 解析输入的电阻字符串
	target := Parse_resistance(resistanceStr)

	// 生成所有可能的 E24 电阻值
	allValues := Generate_all_e24_values(-1, 6)

	// 创建结果结构体
	result := ResistorResult{
		TargetResistance: Format_resistance(target),
	}

	// 查找最接近的单个电阻
	closest, error := Find_closest_single_resistor(target, allValues)
	result.ClosestSingle = SingleResistorResult{
		Value: Format_resistance(closest),
		Error: error * 100,
	}

	// 查找最佳串联组合
	seriesResults := FindSeriesCombinations(target, allValues, 5)
	result.SeriesCombos = make([]CombinationResult, len(seriesResults))
	for i, combo := range seriesResults {
		r1, r2, total, err := combo[0], combo[1], combo[2], combo[3]
		result.SeriesCombos[i] = CombinationResult{
			R1:    Format_resistance(r1),
			R2:    Format_resistance(r2),
			Total: Format_resistance(total),
			Error: err * 100,
		}
	}

	// 查找最佳并联组合
	parallelResults := FindParallelCombinations(target, allValues, 5)
	result.ParallelCombos = make([]CombinationResult, len(parallelResults))
	for i, combo := range parallelResults {
		r1, r2, total, err := combo[0], combo[1], combo[2], combo[3]
		result.ParallelCombos[i] = CombinationResult{
			R1:    Format_resistance(r1),
			R2:    Format_resistance(r2),
			Total: Format_resistance(total),
			Error: err * 100,
		}
	}

	// 将结果转换为JSON字符串
	jsonData, err := json.MarshalIndent(result, "", "  ")
	if err != nil {
		return "", fmt.Errorf("JSON编码错误: %v", err)
	}

	return string(jsonData), nil
}
